/*
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package utopiaintelpackage.kd;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import org.jibble.pircbot.Colors;

import tools.UtopiaTime;
import utopiaintelpackage.AbstractIntel;
import botobjects.Province;

/**
 * This class represents a KD A KD also has Province objects in it The class offers convenience methods for adding and removing
 * commonly used parameters
 * 
 * 
 */
public class KD extends AbstractIntel {
   private final List<Province> provs = new ArrayList<Province>();
   private int amountOfProvs = 0;

   public void addProvince(final String name, final String race, final String personality, final int land, final int nw,
		 final String title) {
	  Province prov = new Province(name, getLoc(), race, personality, title, land, nw);
	  provs.add(prov);
   }

   public int getAmountOfProvs() {
	  return amountOfProvs;
   }

   public String getComment() {
	  if (getParameter("comment") == null)
		 return "";
	  return (String) getParameter("comment");
   }

   public String getDragon() {
	  if (getParameter("dragon") == null)
		 return "";
	  return (String) getParameter("dragon");
   }

   @Override
   public List<String> getIRCOutput(final boolean shortVersion) {
	  List<String> out = new LinkedList<String>();
	  out.add(Colors.OLIVE + "The kingdom of " + Colors.BLUE + getName() + " " + getLoc() + Colors.OLIVE + " Updated: "
			+ Colors.BLUE + UtopiaTime.compareTimes(getUpdated().getTime()) + " ago");

	  final HashMap<String, Integer> races = new HashMap<String, Integer>();
	  final HashMap<String, Integer> titles = new HashMap<String, Integer>();
	  final HashMap<String, Integer> personalities = new HashMap<String, Integer>();
	  int nw = 0, land = 0;
	  int provs = 0;
	  for (Province province : getProvs()) {
		 if (races.containsKey(province.getRace())) {
			races.put(province.getRace(), races.get(province.getRace()) + 1);
		 } else {
			races.put(province.getRace(), 1);
		 }
		 if (titles.containsKey(province.getTitle())) {
			titles.put(province.getTitle(), titles.get(province.getTitle()) + 1);
		 } else {
			titles.put(province.getTitle(), 1);
		 }
		 if (personalities.containsKey(province.getPersonality())) {
			personalities.put(province.getPersonality(), personalities.get(province.getPersonality()) + 1);
		 } else {
			personalities.put(province.getPersonality(), 1);
		 }
		 nw += province.getNw();
		 land += province.getLand();
		 ++provs;
	  }
	  final NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
	  nf.setGroupingUsed(true);
	  nf.setMaximumFractionDigits(1);
	  nf.setMinimumFractionDigits(0);

	  out.add(Colors.OLIVE + "NW: " + Colors.BLUE + nf.format(nw) + Colors.OLIVE + " Avg NW: " + Colors.BLUE
			+ nf.format(nw / Math.max(provs, 1)) + Colors.OLIVE + " Land: " + Colors.BLUE + nf.format(land) + Colors.OLIVE
			+ " Avg Land: " + Colors.BLUE + nf.format(land / Math.max(provs, 1)));

	  String output = "";
	  for (final Entry<String, Integer> e : races.entrySet()) {
		 output += Colors.NORMAL + e.getValue() + " " + Colors.BLUE + e.getKey() + " ";
	  }
	  out.add(Colors.OLIVE + "Races: " + output);

	  output = "";
	  for (final Entry<String, Integer> e : titles.entrySet()) {
		 output += Colors.NORMAL + e.getValue() + " " + Colors.BLUE + e.getKey() + " ";
	  }
	  out.add(Colors.OLIVE + "Titles: " + output);

	  output = "";
	  for (final Entry<String, Integer> e : personalities.entrySet()) {
		 output += Colors.NORMAL + e.getValue() + " " + Colors.BLUE + e.getKey() + " ";
	  }
	  out.add(Colors.OLIVE + "Personalities: " + output);

	  out.add(Colors.OLIVE + "Comment: " + Colors.BLUE + getComment());
	  return out;
   }

   public int getLand() {
	  int land = 0;
	  for (Province p : provs) {
		 land += p.getLand();
	  }
	  return land;
   }

   public String getLoc() {
	  if (getParameter("loc") == null)
		 return "";
	  return (String) getParameter("loc");
   }

   public String getName() {
	  if (getParameter("name") == null)
		 return "";
	  return (String) getParameter("name");
   }

   public int getNW() {
	  int nw = 0;
	  for (Province p : provs) {
		 nw += p.getNw();
	  }
	  return nw;
   }

   public List<Province> getProvs() {
	  return provs;
   }

   @Override
   public Map<String, Object> getRPCOutput(final int... args) {
	  Map<String, Object> out = new HashMap<String, Object>();
	  out.put("Name", getName());
	  out.put("KD", getLoc());
	  out.put("Land", getLand());
	  out.put("NW", getNW());
	  out.put("Dragon", getDragon());
	  out.put("Comment", getComment());
	  out.put("Stance", getStance());
	  out.put("At War", isAtWar());
	  out.put("Show KD", showKD());
	  out.put("Added Time", getUpdated());
	  List<Map<String, Object>> provinces = new LinkedList<Map<String, Object>>();
	  for (Province p : getProvs()) {
		 provinces.add(p.getRPCOutput());
	  }
	  out.put("Province List", provinces);
	  return out;
   }

   public String getStance() {
	  if (getParameter("stance") == null)
		 return "";
	  return (String) getParameter("stance");
   }

   @Override
   public String getTypeOfIntel() {
	  return "KD";
   }

   public Date getUpdated() {
	  return (Date) getParameter("updated");
   }

   public boolean isAtWar() {
	  if (getParameter("atwar") == null)
		 return false;
	  return (Boolean) getParameter("atwar");
   }

   @Override
   public boolean isComplete() {
	  for (final Province p : getProvs()) {
		 if (!p.isComplete())
			return false;
	  }
	  return getParameter("name") != null && getParameter("loc") != null
			&& getParameter("updated") != null && !getProvs().isEmpty();
   }

   public void setAmountOfProvs(final int amountOfProvs) {
	  this.amountOfProvs = amountOfProvs;
   }

   public void setAtWar(final boolean atwar) {
	  setParameter("atwar", atwar);
   }

   public void setComment(final String comment) {
	  setParameter("comment", comment);
   }

   public void setDragon(final String dragon) {
	  setParameter("dragon", dragon);
   }

   public void setLoc(final String loc) {
	  setParameter("loc", loc);
   }

   public void setName(final String name) {
	  setParameter("name", name);
   }

   public void setShow(final boolean show) {
	  setParameter("showkd", show);
   }

   public void setStance(final String stance) {
	  setParameter("stance", stance);
   }

   public void setUpdated(final Date updated) {
	  setParameter("updated", updated);
   }

   public boolean showKD() {
	  if (getParameter("showkd") == null)
		 return false;
	  return (Boolean) getParameter("showkd");
   }
}
